using System;
using System.Collections.Generic;
using System.Data;
using System.Workflow.ComponentModel;
using System.Workflow.Activities;
using Microsoft.Crm.Workflow;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using System.IO;
using System.Web;
using System.Xml;
using System.Linq;
using System.Xml.Linq;
using System.Collections.Specialized;
using MSA.Integration;
using Microsoft.Crm.Sdk.Query;

namespace MSA.SocialNetworking
{
    [CrmWorkflowActivity("Get Replies", "MSA Social Networking")]
    public partial class GetReplies : Activity
    {

        // Override this method with our custom logic
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            //Get the Guid from the Workflow
            IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));
            IWorkflowContext ctx = contextService.Context;
            ICrmService crmService = ctx.CreateCrmService();
            string recordId = ctx.PrimaryEntityId.ToString();
            string _xslt = string.Empty;

            //Get Integration Configuration from CRM i.e. XSLT transform
            ColumnSet cset = new ColumnSet(new String[] { "msa_integrationconfigurationid", "msa_configstring" });
            try
            {
                DynamicEntity dataset = inbound.CrmSearch("msa_integrationconfiguration", "msa_name", "Twitter.GetReplies", cset, crmService);
                _xslt = dataset["msa_configstring"].ToString();
            }
            catch(Exception e)
            {
                this.ReturnStatus = LastId;
                return base.Execute(executionContext);
            }
            //end xslt
            Boolean debugflag;

            if (Debug == "true")
            {
                debugflag = true;
            }
            else
            {
                debugflag = false;
            }

            XDocument xDoc = new XDocument();
            var xDocs = new List<XDocument>();
            var sReplies = new List<String>();

            string since_id = LastId;
            msa_twitter twGetReplies = new msa_twitter();

            twGetReplies.SetCredentials(UserName, Password);
            string returnXml = twGetReplies.GetReplies(LastId);
            
            //There may be more pages
            try
            {
                xDoc = XDocument.Parse(returnXml);
                int i = 1;
                since_id = xDoc.Root.Elements("status").First().Element("id").Value;
                sReplies.Add(returnXml);

                while (xDoc.Root.Elements("status").Count() == 20)
                {
                    twGetReplies.SetCredentials(UserName, Password);
                    returnXml = twGetReplies.GetReplies(LastId, (++i).ToString());
                    xDoc = XDocument.Parse(returnXml);
                    if (xDoc.Root.Elements("status").Count() != 0)
                    {
                        sReplies.Add(returnXml);
                    }
                }
            }
            catch (ArgumentNullException)
            {
                //status element does not contain the right attributes
                if (sReplies.Count == 0)
                {
                    since_id = LastId;
                }
                
            }
            catch (NullReferenceException)
            {
                //status element does not contain the right attributes
                if (sReplies.Count == 0)
                {
                    since_id = LastId;
                }
                
            }
            catch (InvalidOperationException)
            {
                if (sReplies.Count == 0)
                {
                    since_id = LastId;
                }
            }

            if (sReplies.Count > 0)
            {
                try
                {
                    for (int ixml = 0; ixml < sReplies.Count; ixml++)
                    {
                        inbound.CrmTransaction(crmService, msa_transformation.Transform(sReplies[ixml], _xslt, debugflag));
                        //this.ReturnStatus = since_id;
                    }
                }
                catch (NullReferenceException)
                {
                    //status element does not contain the right attributes
                    since_id = LastId;
                }
                catch (InvalidOperationException)
                {
                    //The resultset is null
                    since_id = LastId;
                }
            }
        //garbage disposal
        _xslt = null;
        xDoc = null;
        this.ReturnStatus = since_id;
        return base.Execute(executionContext);
        }

        // Allow the user to set the Username that authenticates to Twitter 
        public static DependencyProperty UserNameProperty = DependencyProperty.Register("UserName", typeof(string), typeof(GetReplies));
        [CrmInput("UserName")]
        public string UserName
        {
            get { return (string)base.GetValue(UserNameProperty); }
            set { base.SetValue(UserNameProperty, value); }
        }

        // Allow the user to set the Password 
        public static DependencyProperty PasswordProperty = DependencyProperty.Register("Password", typeof(string), typeof(GetReplies));
        [CrmInput("Password")]
        public string Password
        {
            get { return (string)base.GetValue(PasswordProperty); }
            set { base.SetValue(PasswordProperty, value); }
        }

        public static DependencyProperty LastIdProperty = DependencyProperty.Register("LastId", typeof(string), typeof(GetReplies));
        [CrmInput("Last Id")]
        public string LastId
        {
            get { return (string)base.GetValue(LastIdProperty); }
            set { base.SetValue(LastIdProperty, value); }
        }

        public static DependencyProperty DebugProperty = DependencyProperty.Register("Debug", typeof(string), typeof(GetReplies));
        [CrmInput("Debug")]
        public string Debug
        {
            get { return (string)base.GetValue(DebugProperty); }
            set { base.SetValue(DebugProperty, value); }
        }

        // Returns the formatted email MailTo Url to the workflow rule for use  
        public static DependencyProperty ReturnStatusProperty = DependencyProperty.Register("ReturnStatus", typeof(string), typeof(GetReplies));
        [CrmOutput("ReturnStatus")]
        public string ReturnStatus
        {
            get { return (string)base.GetValue(ReturnStatusProperty); }
            set { base.SetValue(ReturnStatusProperty, value); }
        }
    }
}